# _*_coding:utf-8_*_
"""
该文件用于对mongo 中的数据查询，解析，并增加，更新 对应的解析后的字段


"""


import asyncio
import os
import sys
import time
import json
import traceback

project_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
print(project_path)
sys.path.append(project_path)

# 打印所有python解释器可以搜索到的所有路径
print(sys.path)


from Freepatentsonline.databases.mongo_handler import Mongo_handler
from Freepatentsonline.extract.extract_async import Extract
from Freepatentsonline.settings import (CONFIG_DIR, CONFIG_FILENAME,
                                        DB_CONFIG_FILENAME)
from Freepatentsonline.utils.path_file import get_config




# 数据库配置文件
DB_CONFIG = get_config(CONFIG_DIR, DB_CONFIG_FILENAME)



# 获取到 mongo 存储数据库配置信息
MONGO_CONFIG = DB_CONFIG["MONGO"]

EXTRACTED_STATUS = 10

class Extract_update:
    def __init__(self) -> None:

        self.extractor = Extract()
        self.mongo = Mongo_handler(MONGO_CONFIG)

        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.run())

    async def run(self):
        """"""
        collection_names = self.mongo.db.list_collection_names()
        
        total_count = 0
        # 存储更新异常的数据
        error_li = []

        for collection_name in collection_names:
            # collection_name = _collection["name"]
            print(f"当前collection :{collection_name}")
            collection = self.mongo.db[collection_name]
            # 查询数据
            while 1:
                data_li = collection.find({"$or":[
                                                    {"extract_status": {"$exists": False}},
                                                    {"extract_status":0},
                                                    {"extract_status":1},
                                                    {"extract_status":2},
                                                    {"extract_status":3},
                                                    {"extract_status":4},
                                                    {"extract_status":5},
                                                    
                                                  ]}, 
                                          {"task_id": 1, "source_text": 1 }
                                          ).limit(100)
                                    

                count = 0
                for data in data_li:
                    filter_data, extract_result = await self.handle_data(data)
                    # 构建更新数据包
                    
                    update_data = {'$set':  extract_result}
                    
                    try:
                        
                        collection.update_one(filter_data, update_data)
                        count +=1 
                        total_count +=1
                        print(f"更新完成：{total_count}条...")
                    except :
                        print(traceback.format_exc())
                        filter_data["_id"] = str(filter_data["_id"])
                        error_info = {
                            "filter_data":filter_data,
                            "update_data":update_data,
                            "traceback_info":traceback.format_exc()
                        }
                        error_li.append(error_info)

                        
                        

                if count < 100:
                    break
            # break
        await self.log_error(error_li)


    async def handle_data(self, data):
        """
        解析查询出来的数据,并返回更新的条件数据和解析后的数据
        """

        filter_data = {"_id": data["_id"]}
        
        extract_result = await self.extractor.extract(data["source_text"],data["task_id"])

        # 修改 extract_status ，该字段用于标识是否解析过数据
        extract_result["extract_status"] = EXTRACTED_STATUS
        # extract_result["extract_update_time"] = int(time.time())
        
        
        return filter_data, extract_result
    
    async def log_error(self,error_li):
        """
        在更新结束后，记录存储文件
        """
        # 记录异常数据
        if error_li:
            filename_error = f"error_{int(time.time())}.json"
        
            with open(filename_error,"w",encoding="utf-8")as f:
                json.dump(error_li,f,ensure_ascii=False)
                print(f"异常数据日志文件： {filename_error} 保存成功 ...")
        else:
            print("异常数据日志文件： 列表为空，无需记录...")

        
        # 记录空 key 的数据
        if self.extractor.empty_key_li:
            filename_empty_key = f"empty_key_{int(time.time())}.json"
            with open(filename_empty_key,"w",encoding="utf-8")as f:
                json.dump(list(self.extractor.empty_key_li),f,ensure_ascii=False)
                print(f"empty key 文件： {filename_empty_key} 保存成功 ...")
        else:
            print("empty key 列表为空，无需记录...")



if __name__ == "__main__":
    extract_update = Extract_update()
